package com.winner.service;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * springboot中bean的几种初始化方法与销毁方法的执行顺序
 *  我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法
 *      1：在配置类中 @Bean(initMethod = "init",destroyMethod = "destory")注解指定
 *      2：实现InitializingBean接口重写其afterPropertiesSet方法，实现DisposableBean接口重写destroy方法
 *      3：利用java的JSR250规范中的@PostConstruct标注在init方法上，@PreDestroy标注在destroy注解上
 */
//我今天学习到SpringBoot里面自定义Bean的初始化与销毁方法
//方法一：
//指定init-method 和 destory-method
//
//方法二：
//通过让 Bean 实现 InitializingBean 接口，定义初始化逻辑
//DisposableBean 接口，定义销毁逻辑
//
//方法三：
//用 @PostConstruct，在 Bean 创建完成并且赋值完成后，执行该注解标注的方法
//@PreDestroy，在容器销毁 Bean 之前，执行该注解标注的方法
//
//方法四：
//通过让 Bean 实现 BeanPostProcessor 接口，在Bean 初始化前后进行一些处理工作
//postProcessBeforeInitialization: 在初始化之前工作
//postProcessAfterInitialization: 在初始化之后工作
// 后置处理器BeanPostProcessor底层原理
//	BeanPostProcessor接口：bean的后置处理器，其有两个方法
//			postProcessBeforeInitialization:在初始化之前工作
//			postProcessAfterInitialization:在初始化之后工作
@Service
public class MainConfigOfLifeCycle implements InitializingBean, DisposableBean,BeanPostProcessor {

    @PostConstruct
    public void postConstructTest() throws Exception {
        System.out.println(" .. @PostConstruct .. ");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(" .. InitializingBean afterPropertiesSet执行 .. ");
    }

    @Bean(initMethod = "init")
    public void init() throws Exception {
        // bean初始化时就会执行bean的initMethod初始化方法, 和 extends InitializingBean重写afterPropertiesSet方法达到一样的效果
        System.out.println(" .. initMethod执行, bean初始化时");
    }

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(" .. postProcessBeforeInitialization .. ");
//		System.out.println("bean初始化完成");
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(" .. postProcessAfterInitialization .. ");
		return bean;
	}

	@Bean(destroyMethod = "destroyMethod")
	public void destroyMethod() throws Exception {
		// bean初始化时就会执行bean的initMethod初始化方法, 和 extends InitializingBean重写afterPropertiesSet方法达到一样的效果
		System.out.println(".. destroyMethod执行");
	}

	@PreDestroy
	public void preDestroyTest() {
		System.out.println(" .. @PreDestroy .. ");
	}

	// implements DisposableBean
    @Override
    public void destroy() throws Exception {
        System.out.println(" .. DisposableBean destroy执行 .. ");
    }



}
